from __future__ import annotations

from typing import Optional

from .events import append_event, read_owner_events


def task_create(memory_dir, owner: str, actor: str, title: str, desc: str, assignees_csv: str):
    headers = {
        "title": title,
        "status": "open",
        "assignees": assignees_csv or "",
    }
    body = desc
    return append_event(memory_dir, owner, actor, "task", body, headers)


def task_discuss(memory_dir, owner: str, actor: str, task_id: str, message: str):
    headers = {"in_reply_to": task_id}
    return append_event(memory_dir, owner, actor, "task_comment", message, headers)


def task_status(memory_dir, owner: str, task_id: str) -> None:
    events = read_owner_events(memory_dir, owner, None)
    root = next((e for e in events if e.id == task_id and e.type == "task"), None)
    if not root:
        print("Task not found")
        return
    status = _effective_status(events, root)
    print(f"Task {root.id} '{root.headers.get('title','')}' status={status} assignees={root.headers.get('assignees','')} by {root.actor} at {root.created_at}")
    if root.content:
        print(root.content)
    print()
    children = [e for e in events if e.headers.get("in_reply_to") == root.id and e.type in ("task_comment","task_update")]
    children.sort(key=lambda e: e.created_at)
    for e in children:
        if e.type == "task_update":
            print(f"- {e.created_at} status -> {e.headers.get('status','')}")
        else:
            print(f"- {e.created_at} {e.actor}: {e.content}")


def task_list(memory_dir, owner: str, assignee: Optional[str], status: Optional[str] = None) -> None:
    events = read_owner_events(memory_dir, owner, None)
    tasks = [e for e in events if e.type == "task"]
    tasks.sort(key=lambda e: e.created_at, reverse=True)
    for t in tasks:
        if assignee and assignee not in (t.headers.get("assignees", "")):
            continue
        st = _effective_status(events, t)
        if status and st != status:
            continue
        print(f"{t.created_at} id={t.id} status={st} title={t.headers.get('title','')}")


def _effective_status(events, task_event) -> str:
    status = task_event.headers.get("status", "open")
    updates = [e for e in events if e.headers.get("in_reply_to") == task_event.id and e.type == "task_update"]
    if not updates:
        return status
    updates.sort(key=lambda e: e.created_at)
    last = updates[-1]
    return last.headers.get("status", status)


def task_update_status(memory_dir, owner: str, actor: str, task_id: str, status: str):
    headers = {"in_reply_to": task_id, "status": status}
    return append_event(memory_dir, owner, actor, "task_update", "", headers)
